package com.paranoidmonkey.ode;

import java.util.ArrayList;
import java.util.List;

import android.util.Log;

public class Space extends ODEObject{

	private Space(long handle){
		this.handle=handle;
	}
	
	public static Space createSimpleSpace (Space space){
		long handle=0;
		if (space!=null) handle=space.handle;
		return new Space(AndrODE.dSimpleSpaceCreate(handle));
	}
	public static Space createHashSpace(Space space){
		long handle=0;
		if (space!=null) handle=space.handle;
		return new Space(AndrODE.dHashSpaceCreate(handle));
	}
	public static Space createQuadTreeSpace(Space space,  Vector3 Center,  Vector3 Extents, int Depth){
		long handle=0;
		if (space!=null) handle=space.handle;
		return new Space(AndrODE.dQuadTreeSpaceCreate(handle,Center.data,Extents.data,Depth));
	}
	public static Space createSweepAndPruneSpace(Space space, int axisorder){
		long handle=0;
		if (space!=null) handle=space.handle;
		return new Space(AndrODE.dSweepAndPruneSpaceCreate(handle,axisorder));
	}
	public void destroy(){
		AndrODE.dSpaceDestroy (handle);
	}
	public void setHashSpaceLevels(int minlevel, int maxlevel){
		AndrODE.dHashSpaceSetLevels (handle, minlevel, maxlevel);
	}
	public void getHashSpaceLevels(int[] minlevel, int[] maxlevel){
		AndrODE.dHashSpaceGetLevels (handle, minlevel, maxlevel);
	}
	public void setCleanup(int mode){
		AndrODE.dSpaceSetCleanup (handle, mode);
	}
	public int getCleanup(){
		return AndrODE.dSpaceGetCleanup (handle);
	}
	public void setSublevel(int sublevel){
		AndrODE.dSpaceSetSublevel (handle, sublevel);
	}
	public int getSublevel(){
		return AndrODE.dSpaceGetSublevel (handle);
	}
	public void setManualCleanup(int mode){
		AndrODE.dSpaceSetManualCleanup (handle, mode);
	}
	public int getManualCleanup(){
		return AndrODE.dSpaceGetManualCleanup (handle);
	}
	public void add(Geom geom){
		AndrODE.dSpaceAdd (handle, geom.handle);
	}
	public void remove(Geom geom){
		AndrODE.dSpaceRemove (handle, geom.handle);
	}
	public int query(Geom geom){
		return AndrODE.dSpaceQuery (handle, geom.handle);
	}
	public void clean(){
		AndrODE.dSpaceClean (handle);
	}
	public int getNumGeoms(){
		return AndrODE.dSpaceGetNumGeoms (handle);
	}
	public Geom getGeom(int i){
		return new Geom(AndrODE.dSpaceGetGeom (handle, i));
	}
	public int getODEClass(){
		return AndrODE.dSpaceGetClass(handle);
	}

	public boolean equals(Object b){
		if (b instanceof Space) {
			if (((Space)b).handle==handle){
				return true;
			}
		}
		return false;
	}

	private static List<ODECollisionListener> collisionListeners=new ArrayList<ODECollisionListener>();
	
	public static void addCollisionListener(ODECollisionListener l){
		if (collisionListeners.contains(l)) return;
		collisionListeners.add(l);
	}
	public static void removeCollisionListener(ODECollisionListener l){
		collisionListeners.remove(l);
	}
	public static void clearCollisionListeners(){
		collisionListeners.clear();
	}
	
	protected static void dispatchCollision(long o1,long o2){
		Log.d("Space","collision dispatched");
		Geom g1=new Geom(o1), g2=new Geom(o2);
		
		for (ODECollisionListener l:collisionListeners){
			l.collide(g1,g2);
		}
	}
	
	public void collide(){
		AndrODE.collideNative(handle);
	}
	
	public void collideCleanup(){
		for (ODECollisionListener l:collisionListeners){
			l.collisionCleanup();
		}
	}
}
